package com.my.ph.util;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.mime.MultipartEntityBuilder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;
import java.util.zip.GZIPInputStream;

@Slf4j
public class HttpClientUtil {

    private static final HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(20)).build();

    public static <T> HttpResponse<T> get(String url, Map<String, String> headers, HttpResponse.BodyHandler<T> bodyHandler) {
        System.setProperty("jdk.httpclient.allowRestrictedHeaders", "connection,content-length,expect,host,upgrade");
        try {
            HttpRequest.Builder requestBuild = HttpRequest.newBuilder()
                    .uri(URI.create(url));
            headers.forEach(requestBuild::header);
            return client.send(requestBuild.GET().build(), bodyHandler);
        } catch (IOException | InterruptedException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("请求发生异常");
        }
    }

    public static HttpResponse<String> get(String url, Map<String, String> headers) {
        return get(url, headers, HttpResponse.BodyHandlers.ofString());
    }

    public static String getISToString(String url, Map<String, String> headers) {
        try {
            HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url)).GET();
            headers.forEach(builder::header);
            HttpResponse<InputStream> response = client.send(builder.build(), HttpResponse.BodyHandlers.ofInputStream());
            HttpHeaders responseHeader = response.headers();
            InputStream inputStream = responseHeader.firstValue("content-encoding").map(item -> StrUtil.contains(item, "gzip")).orElse(false) ?
                    new GZIPInputStream(response.body()) : response.body();
            String body = IoUtil.read(inputStream, StandardCharsets.UTF_8);
            IoUtil.close(inputStream);
            return body;
        } catch (IOException | InterruptedException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("请求发生异常");
        }
    }

    public static HttpResponse<String> filePost(String url, File file, Map<String, String> params, Map<String, String> headers) {
        try {
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create()
                    .addBinaryBody("file", file);
            if (params != null) params.forEach(multipartEntityBuilder::addTextBody);
            HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url)).POST(HttpRequest.BodyPublishers.ofInputStream(() -> {
                try {
                    return multipartEntityBuilder.build().getContent();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }));
            headers.forEach(builder::header);
            return client.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        }  catch (IOException | InterruptedException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("请求发生异常");
        }
    }

}
